package com.maoshi.shop.user.api.listener;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maoshi.shop.bean.app.dto.ShopCartItemDiscountDto;
import com.maoshi.shop.bean.app.dto.ShopCartItemDto;
import com.maoshi.shop.bean.app.dto.ShopCartOrderDto;
import com.maoshi.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.maoshi.shop.bean.app.param.OrderParam;
import com.maoshi.shop.bean.event.PlatformConfirmOrderEvent;
import com.maoshi.shop.bean.model.Category;
import com.maoshi.shop.bean.model.UserExtension;
import com.maoshi.shop.bean.order.ConfirmOrderOrder;
import com.maoshi.shop.bean.param.ScoreConfigParam;
import com.maoshi.shop.common.config.Constant;
import com.maoshi.shop.common.util.Arith;
import com.maoshi.shop.security.api.util.SecurityUtils;
import com.maoshi.shop.service.CategoryService;
import com.maoshi.shop.service.SysConfigService;
import com.maoshi.shop.service.UserExtensionService;
import com.maoshi.shop.user.comment.dao.UserLevelMapper;
import com.maoshi.shop.user.comment.model.UserLevel;
import com.maoshi.shop.user.comment.util.CategoryScale;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 计算订单时的积分及成长值抵现和折扣信息
 */
@Component("userConfirmOrderListener")
@AllArgsConstructor
public class ConfirmOrderListener {

    private final UserExtensionService userExtensionService;
    private final SysConfigService sysConfigService;
    private final UserLevelMapper userLevelMapper;
    private final CategoryService categoryService;

    /**
    *  计算积分抵现和分摊
    */
    @EventListener(PlatformConfirmOrderEvent.class)
    @Order(ConfirmOrderOrder.SCORE)
    public void scoreSubmitOrderListener(PlatformConfirmOrderEvent event) {
        //获取用户等级积分详细表
        UserExtension extension = userExtensionService.getOne(
                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, SecurityUtils.getUser().getUserId()));
        //获取配置信息
        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG,ScoreConfigParam.class);
        if(Objects.isNull(scoreParam) || extension.getScore() <= 0){
            return;
        }
        ShopCartOrderMergerDto shopCartOrderMergerDto = event.getShopCartOrderMergerDto();
        OrderParam orderParam = event.getOrderParam();
        //计算积分最多抵现金额
        double totalScoreAmount = 0.0;
        List<Category> categories = categoryService.listByShopId(Constant.PLATFORM_SHOP_ID);
        Map<Long, Double> categoryMap = CategoryScale.getScaleByCategory(categories,scoreParam,0);
        //积分抵现金额可用上限 = 订单可使用积分比例 * ((实际总值)/100）
        if(scoreParam.getUseDiscountRange() == 0){
            totalScoreAmount = Arith.div(Arith.mul(shopCartOrderMergerDto.getActualTotal(), scoreParam.getUseDiscount()), 100);
        }else{
            //获取大类的比例并转成map
            for (ShopCartItemDto shopCartItem : event.getAllCartItem()) {
                if(!categoryMap.containsKey(shopCartItem.getCategoryId())) {
                    continue;
                }
                double scoreReduce = Arith.div(Arith.mul(shopCartItem.getActualTotal(), categoryMap.get(shopCartItem.getCategoryId())),100);
                totalScoreAmount = Arith.add(totalScoreAmount,scoreReduce);
            }
        }
        //计算用户可用积分 如果大于总共的积分使用比例直接使用，如果小于根据比例使用
        int canUseScore = (int) Arith.mul(totalScoreAmount, scoreParam.getShopUseScore());
        double scale = 1.0;
        if(extension.getScore() < canUseScore){
            scale = Arith.div(extension.getScore(), canUseScore);
            totalScoreAmount = Arith.div(extension.getScore(),scoreParam.getShopUseScore());
            canUseScore = extension.getScore();
        }
        if (canUseScore == 0) {
            return;
        }
        //用户选择积分抵现，组装积分信息
        List<ShopCartOrderDto> shopCartOrders = shopCartOrderMergerDto.getShopCartOrders();
        double totalScoreReduce = 0.0;
        int totalScore = 0;
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            double reduceSum = 0.0;
            int shopScore = 0;
            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> shopCartItems = shopCartItemDiscount.getShopCartItems();
                for (ShopCartItemDto shopCartItem : shopCartItems) {
                    double scoreReduceProd = 0.0;
                    //计算商品分摊的金额，需要乘以比例
                    if(scoreParam.getUseDiscountRange() == 0){
//                        scoreReduceProd = Arith.mul(Arith.div(shopCartItem.getActualTotal(), 100), scoreParam.getUseDiscount());
                        scoreReduceProd = Arith.div(Arith.mul(shopCartItem.getActualTotal(),scoreParam.getUseDiscount()),100,2);
                    }else if(categoryMap.containsKey(shopCartItem.getCategoryId())){
                        scoreReduceProd = Arith.div(Arith.mul(shopCartItem.getActualTotal(),categoryMap.get(shopCartItem.getCategoryId())),100,2);
                    }
                    scoreReduceProd = Arith.mul(scoreReduceProd,scale);
                    //如果大于可用上限则直接等于
                    if(Arith.add(totalScoreReduce,scoreReduceProd) > totalScoreAmount){
                        scoreReduceProd = Arith.sub(totalScoreAmount ,totalScoreReduce);
                    }
                    totalScoreReduce = Arith.add(totalScoreReduce, scoreReduceProd);
                    reduceSum = Arith.add(reduceSum, scoreReduceProd);
                    shopScore += (int) Arith.mul(scoreReduceProd, scoreParam.getShopUseScore());
                    if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
                        double platformReduce = shopCartItem.getPlatformShareReduce() == null?0:shopCartItem.getPlatformShareReduce();
                        shopCartItem.setPlatformShareReduce(Arith.add(platformReduce, scoreReduceProd));
                        shopCartItem.setScorePayReduce(scoreReduceProd);
                        shopCartItem.setScorePrice((int) Arith.mul(scoreReduceProd, scoreParam.getShopUseScore()));
//                        shopCartItem.setActualTotal(Arith.sub(shopCartItem.getActualTotal(), scoreReduceProd));
//                        shopCartItem.setShareReduce(Arith.add(shopCartItem.getShareReduce(),shopCartItem.getPlatformShareReduce()));
                    }
                }
            }
            //设置店铺的实际总值、积分优惠金额和订单优惠金额
            shopCartOrder.setScoreReduce(reduceSum);
            totalScore += shopScore;
            if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
//                shopCartOrder.setShopReduce(Arith.add(shopCartOrder.getShopReduce(), reduceSum));
//                shopCartOrder.setActualTotal(Arith.sub(shopCartOrder.getActualTotal(), reduceSum));
                shopCartOrder.setUseScore(shopScore);
            }
        }
        //设置订单的实际总值和订单优惠金额
        shopCartOrderMergerDto.setTotalScoreAmount(totalScoreReduce);
        shopCartOrderMergerDto.setTotalUsableScore(totalScore);
        if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
//            shopCartOrderMergerDto.setActualTotal(Arith.sub(shopCartOrderMergerDto.getActualTotal(), totalScoreReduce));
//            shopCartOrderMergerDto.setOrderReduce(Arith.add(shopCartOrderMergerDto.getOrderReduce(), totalScoreReduce));
            shopCartOrderMergerDto.setScorePrice(totalScore);
        }
    }

    /**
     *  计算等级折扣比例和分摊比例
     */
    @EventListener(PlatformConfirmOrderEvent.class)
    @Order(ConfirmOrderOrder.LEVEL)
    public void levelSubmitOrderListener(PlatformConfirmOrderEvent event) {
        UserExtension extension = userExtensionService.getOne(
                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, SecurityUtils.getUser().getUserId()));
        if (extension == null) {
            return;
        }
        UserLevel level = userLevelMapper.selectOneAndCategory(extension);
        if (level == null || level.getDiscount() > 10) {
            return;
        }
        ShopCartOrderMergerDto shopCartOrderMergerDto = event.getShopCartOrderMergerDto();
        List<ShopCartOrderDto> shopCartOrders = shopCartOrderMergerDto.getShopCartOrders();
        //获取分类比例
        //最后计算成长值折扣
        if (extension.getLevel() == null) {
            extension.setLevel(Constant.USER_LEVEL_INIT);
        }
        double levelDiscount = 0.0;
        double freeTransfee = 0.0;
        double levelDiscountActualTotal= 0.0;
        double discount = Arith.sub(10,level.getDiscount());
        //将分类转成map
        List<Long> categoryIds = level.getCategoryIds();
        Map<Long,Long> categoryMap = new HashMap<>(100);
        if(CollectionUtils.isNotEmpty(categoryIds)){
            categoryIds.forEach(categoryId -> categoryMap.put(categoryId,categoryId));
        }
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            //如果可用范围为自营店不为当前店铺直接下一次循环
            if(level.getDiscountRange() == 1 && !Objects.equals(shopCartOrder.getShopId(),1L)){
                continue;
            }
            double reduceSum = 0.0;
            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> shopCartItems = shopCartItemDiscount.getShopCartItems();
                for (ShopCartItemDto shopCartItem : shopCartItems) {
                    double prodDiscount = 0.0;
                    //折扣
                    if(level.getDiscountType() == 0 || categoryMap.containsKey(shopCartItem.getCategoryId())){
                        prodDiscount = Arith.div(Arith.mul(shopCartItem.getActualTotal(),discount),10,2);
                        //获取所有订单项等级折扣金额的总和
                        levelDiscountActualTotal  = Arith.add(levelDiscountActualTotal,shopCartItem.getActualTotal());
                    }
                    //计算商品分摊的金额
                    shopCartItem.setPlatformShareReduce(Arith.add(shopCartItem.getPlatformShareReduce() , prodDiscount));
                    reduceSum = Arith.add(reduceSum, Arith.round(prodDiscount,2));
                }
            }
            //设置店铺的实际总值、积分优惠金额和订单优惠金额
            shopCartOrder.setLevelReduce(reduceSum);
            levelDiscount = Arith.add(levelDiscount, reduceSum);
            //判断用户等级是否自营店包邮
            //&& level.getCategoryIds()
            if(Objects.equals(shopCartOrder.getShopId(), Constant.MAIN_SHOP) && level.getIsFreeFee() == 1){
                freeTransfee = shopCartOrder.getTransfee();
                shopCartOrder.setScoreReduce(Arith.add(shopCartOrder.getShopReduce(),shopCartOrder.getTransfee()));
                shopCartOrder.setFreeTransfee(shopCartOrder.getTransfee());
                shopCartOrder.setTransfee(0.0);
            }
        }
        shopCartOrderMergerDto.setTotalLevelAmount(levelDiscount);
        //设置运费优惠金额
        shopCartOrderMergerDto.setFreeTransfee(freeTransfee);
    }
}
